package com.ruoyi.project.support.phy;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.asymmetric.SignAlgorithm;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.ssl.DefaultTrustManager;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;

import javax.net.ssl.SSLContext;
import java.math.BigDecimal;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.Map;

import static cn.hutool.core.util.CharsetUtil.UTF_8;

/**
 * @ClassName PayUtil
 * @Description
 * @Author Small
 * @Date 2021/1/4 10:16
 * @Version 1.0
 **/
public class PhyPayUtil {


    /**
     * 报文填充
     *
     * @param param
     * @return
     */
    public static Map<String, String> fillData(Map<String, String> param) {
        param.put("version", PhyConst.VERSION);
        param.put("encoding", PhyConst.ENCODING);
        param.put("sign_method", PhyConst.SIGN_METHO);
        // TODO 最后一步
        param.put("signature", genSignature(param));
        return param;
    }


    /**
     * 生成签名
     * @param param
     * @return
     */
    public static String genSignature(Map<String, String> param) {

        String encrypt = null;

        System.out.println(JSON.toJSONString(param));
        String src = param.get("msg_body");
        System.out.println("明文：" + src);
        try {
            byte[] msg_bodies = SecureUtil.sign(SignAlgorithm.SHA1withRSA, loadPraKey(), loadPubKey()).sign(src.getBytes());
            String encode = Base64.encode(msg_bodies);
            encrypt = encode;
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("signature:" + encrypt);
        return encrypt;
    }


    /**
     * 验签
     *
     * @param str       明文
     * @param signstr   签名
     */
    private static void verifySign(String str, String signstr) {
        boolean verify = SecureUtil.sign(SignAlgorithm.SHA1withRSA, loadPraKey(), loadPubKey()).verify(str.getBytes(), Base64.decode(signstr));
        System.out.println(verify);
    }


    public static void aliPay(BigDecimal amount,String orderId) {
        Map<String, String> msgBody = Maps.newHashMap();
        msgBody.put("tran_cd", PhyConst.TRAN_CD_7131);
        msgBody.put("tran_cd", PhyConst.TRAN_CD_1191);
        msgBody.put("acc_mod", PhyConst.ACC_MOD);
        msgBody.put("prod_cd", PhyConst.PROD_CD_1151);
        msgBody.put("biz_cd", PhyConst.BIZ_CD_0000008);
        msgBody.put("mcht_cd", PhyConst.MCHT_CD);
        msgBody.put("tran_dt_tm", DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
        msgBody.put("order_id", orderId);
        String fmtamount = String.valueOf(NumberUtil.mul(amount, 100).intValue());
        msgBody.put("tran_amt", fmtamount);
        msgBody.put("time_out", "60000");

        // 扫码信息域
//        Map<String, String> qrCodeInfo = Maps.newHashMap();
//        qrCodeInfo.put("noti_url", "1111111");
//        msgBody.put("qr_code_info", JSON.toJSONString(qrCodeInfo));



        Map<String, String> param = Maps.newHashMap();
        param.put("msg_body", JSON.toJSONString(msgBody));
        fillData(param);

        System.out.println(JSON.toJSONString(param));

        SSLContext sc = null;
        try {
            sc = SSLContext.getInstance("SSL");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        try {
            sc.init(null, new DefaultTrustManager[]{new DefaultTrustManager()}, new java.security.SecureRandom());
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        HttpRequest httpRequest = HttpUtil.createPost(PhyConst.REQ_URL).setSSLSocketFactory(sc.getSocketFactory())
                .body(JSON.toJSONString(param)).timeout(3000);
        HttpResponse execute = httpRequest.execute();
        String body = execute.body();
        System.out.println("下单返回报文");
        System.out.println(body);


//        String body = JSON.toJSONString(param);
//
        JSONObject jsonObject = JSON.parseObject(body);
        String msg_body = jsonObject.getString("msg_body");
        String signature = jsonObject.getString("signature");
//
//
        verifySign(msg_body, signature);
    }




    private static String loadPraKey() {
        byte[] bytesPra = ResourceUtil.readBytes("cert/pri.key");

        String str = StrUtil.str(bytesPra, UTF_8);

        str = str.replaceAll("(\\r\\n|\\n)", "");
        str = str.replace("-----BEGIN PRIVATE KEY-----", "");
        str = str.replace("-----END PRIVATE KEY-----", "");
        return str;
    }

    private static String loadPubKey() {
        byte[] bytesPub = ResourceUtil.readBytes("cert/pub.key");

        String str = StrUtil.str(bytesPub, UTF_8);

        str = str.replaceAll("(\\r\\n|\\n)", "");
        str = str.replace("-----BEGIN PUBLIC KEY-----", "");
        str = str.replace("-----BEGIN PUBLIC KEY-----", "");
        return str;
    }


    public static void main(String[] args) {
        BigDecimal amount = new BigDecimal("0.01");
        String orderId = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN);
        aliPay(amount,orderId);

    }
}
